///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef __PredefinedControllers_H__
#define __PredefinedControllers_H__

#include "OgrePrerequisites.h"

#include "OgreCommon.h"
#include "OgreController.h"
#include "OgreFrameListener.h"
#include "OgreGpuProgram.h"

namespace Ogre {

	
	
	//-----------------------------------------------------------------------
    // Controller Values
    //-----------------------------------------------------------------------
    
    class _OgreExport FrameTimeControllerValue : public ControllerValue<Real>, public FrameListener
    {
    protected:
        Real mFrameTime;
		Real mTimeFactor;
		Real mElapsedTime;
		Real mFrameDelay;

    public:
        FrameTimeControllerValue();
        bool frameEnded(const FrameEvent &evt);
        bool frameStarted(const FrameEvent &evt);
        Real getValue(void) const;
        void setValue(Real value);
		Real getTimeFactor(void) const;
		void setTimeFactor(Real tf);
		Real getFrameDelay(void) const;
		void setFrameDelay(Real fd);
		Real getElapsedTime(void) const;
		void setElapsedTime(Real elapsedTime);
    };

    //-----------------------------------------------------------------------
    
    class _OgreExport TextureFrameControllerValue : public ControllerValue<Real>
    {
    protected:
        TextureUnitState* mTextureLayer;
    public:
        TextureFrameControllerValue(TextureUnitState* t);

        
        Real getValue(void) const;
        
        void setValue(Real value);

    };
    //-----------------------------------------------------------------------
    
    class _OgreExport TexCoordModifierControllerValue : public ControllerValue<Real>
    {
    protected:
        bool mTransU, mTransV;
        bool mScaleU, mScaleV;
        bool mRotate;
        TextureUnitState* mTextureLayer;
    public:
        
        TexCoordModifierControllerValue(TextureUnitState* t, bool translateU = false, bool translateV = false,
            bool scaleU = false, bool scaleV = false, bool rotate = false );

        Real getValue(void) const;
        void setValue(Real value);

    };

    //-----------------------------------------------------------------------
    
    class _OgreExport FloatGpuParameterControllerValue : public ControllerValue<Real>
    {
    protected:
		/// The parameters to access
		GpuProgramParametersSharedPtr mParams;
		/// The index of the parameter to e read or set
		size_t mParamIndex;
    public:
        
        FloatGpuParameterControllerValue(GpuProgramParametersSharedPtr params,
				size_t index );

        ~FloatGpuParameterControllerValue() {}

        Real getValue(void) const;
        void setValue(Real value);

    };
    //-----------------------------------------------------------------------
    // Controller functions
    //-----------------------------------------------------------------------

	
	class _OgreExport PassthroughControllerFunction : public ControllerFunction<Real>
	{
	public:
		
		PassthroughControllerFunction(bool deltaInput = false);

		
		Real calculate(Real source);
	};

	
    class _OgreExport AnimationControllerFunction : public ControllerFunction<Real>
    {
    protected:
        Real mSeqTime;
        Real mTime;
    public:
        
        AnimationControllerFunction(Real sequenceTime, Real timeOffset = 0.0f);

        
        Real calculate(Real source);

		
		void setTime(Real timeVal);
		
		void setSequenceTime(Real seqVal);
    };

	//-----------------------------------------------------------------------
    
    class _OgreExport ScaleControllerFunction : public ControllerFunction<Real>
    {
    protected:
        Real mScale;
    public:
        
        ScaleControllerFunction(Real scalefactor, bool deltaInput);

        
        Real calculate(Real source);

    };

    //-----------------------------------------------------------------------
    
    class _OgreExport WaveformControllerFunction : public ControllerFunction<Real>
    {
    protected:
        WaveformType mWaveType;
        Real mBase;
        Real mFrequency;
        Real mPhase;
        Real mAmplitude;
		Real mDutyCycle;

        
        Real getAdjustedInput(Real input);

    public:
        
        WaveformControllerFunction(WaveformType wType, Real base = 0, Real frequency = 1, Real phase = 0, Real amplitude = 1, bool deltaInput = true, Real dutyCycle = 0.5);

        
        Real calculate(Real source);

    };
    //-----------------------------------------------------------------------
	
	

}

#endif
